

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

public enum Toolset
{
	LogGabor("lg", "hd"), 
	Ma("qsw", "hd"), 
	Ko("ko", "koc"), 
	RathgebUhl("cr", "hd"), 
	ContextBasedIrisRecognition("cb", "cbc"), 
	Monro("dct", "dctc");

	private static final String _SEG_WAHET_NAME = "wahet";
	private static final String _SEG_CAHT_NAME = "caht";

	private static final String _TOOL_PREFIX = "usit_bin";
	private static final String _EXE_SUFFIX = ".exe"; 			// important if it should run on windows and/or linux
	private static final String _TEXTURE_FILE = "texture.tiff";

	private Toolset(String exeName, String comparator)
	{
		_id = exeName;
		_exeName = new File(_TOOL_PREFIX, exeName + _EXE_SUFFIX);
		_comparator = new File(_TOOL_PREFIX, comparator + _EXE_SUFFIX);
	}

	private File _exeName;
	private File _comparator;
	private File _segmentation = new File(_TOOL_PREFIX, _SEG_WAHET_NAME + _EXE_SUFFIX);
	private File _tmpDir = new File("tmpWorking/");

	private String _id;

	public static final int SEG_WAHET = 1;
	public static final int SEG_CAHT = 2;

	/**
	 * Sets used segmentator, use constants defined SEG_WAHET or SEG_CAHT
	 * 
	 * @param segmentationMethod
	 *                  the segmentation method. Default is WAHET
	 */
	public void setSegmentationMethod(int segmentationMethod)
	{
		if (segmentationMethod == SEG_WAHET)
		{
			_segmentation = new File(_TOOL_PREFIX, _SEG_WAHET_NAME + _EXE_SUFFIX);
		}
		else if (segmentationMethod == SEG_CAHT)
		{
			_segmentation = new File(_TOOL_PREFIX, _SEG_CAHT_NAME + _EXE_SUFFIX);
		}
	}

	/**
	 * The distance is calculated by calling the Distance-Calculator specified in the Toolset (which is related to the used FeatureExtractor). The console output of this
	 * program is read via Output-Stream and processed in order to get the distance between the two images, which where specified in the call of the Distance-Calculator.
	 * 
	 * example call of external programm:
	 * 	hd.exe -i <f1> <f2> -s -8 8
	 * 
	 * @param f1 Iris code 1
	 * @param f2 Iris code 2
	 * @return distance metric
	 * @throws IOException If something goes wrong 
	 * @throws InterruptedException
	 */
	public double calcDistance(File f1, File f2) throws IOException, InterruptedException
	{
		// make sure no old data is there
		_tmpDir.mkdirs();

		String[] params = new String[7];

		// ########## Do segmentation
		params[0] = _comparator.getAbsolutePath();
		params[1] = "-i";
		params[2] = f1.getAbsolutePath();
		params[3] = f2.getAbsolutePath();
		params[4] = "-s";
		params[5] = "-8";
		params[6] = "8";

		ProcessBuilder builder = new ProcessBuilder(params);
		Process pSegment = builder.start();
		pSegment.waitFor();

		BufferedReader output = new BufferedReader(new InputStreamReader(pSegment.getInputStream()));

		String line;
		double dist = -1.0;
		while ((line = output.readLine()) != null)
		{
			// System.out.println(line);

			String parts[] = line.split("=");
			parts[1].replace(" ", "");
			dist = Double.parseDouble(parts[1].replace(" ", ""));
		}

		output.close();

		return dist;
	}

	public String getID()
	{
		return _id;
	}

	public void setTempDirectory(File tmpWorkingDir)
	{
		_tmpDir = tmpWorkingDir;
	}

//	public File getEmptiedWorkingDir()
//	{
//		deleteFolder(_tmpDir);
//		_tmpDir.mkdirs();
//		return _tmpDir;
//	}

	private void deleteFolder(File folder)
	{
		File[] files = folder.listFiles();
		if (files != null)
		{ // some JVMs return null for empty dirs
			for (File f : files)
			{
				if (f.isDirectory())
				{
					deleteFolder(f);
				}
				else
				{
					f.delete();
				}
			}
		}
		folder.delete();
	}

	public boolean calcIrisCode(File inputImage, File outputCodePng) throws IOException, InterruptedException
	{
		// make sure no old data is there
		deleteFolder(_tmpDir);
		_tmpDir.mkdirs();
		new File(outputCodePng.getParent()).mkdirs();

		String[] params = new String[5];
		File texture = new File(_tmpDir, _TEXTURE_FILE);

		// ########## Do segmentation
		params[0] = _segmentation.getAbsolutePath();
		params[1] = "-i";
		params[2] = inputImage.getAbsolutePath();
		params[3] = "-o";
		params[4] = texture.getAbsolutePath();

		ProcessBuilder builder = new ProcessBuilder(params);
		Process pSegment = builder.start();
		pSegment.waitFor();

		// Runtime.getRuntime().exec(params);

		// ok, everything went smoothly (otherwise exc is thrown)

		// ########### Calc iris code, store to output
		params[0] = _exeName.getAbsolutePath();
		params[2] = texture.getAbsolutePath();
		params[4] = outputCodePng.getAbsolutePath();

		builder = new ProcessBuilder(params);
		Process pFeature = builder.start();
		pFeature.waitFor();

		// Runtime.getRuntime().exec(params);

		// clean up after me..

		return true;
	}

}
